package com.timanetworks.endec.core;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.timanetworks.endec.PrivacyEncrypt;

import java.io.IOException;
import java.util.Objects;

public class PrivacySerialize extends JsonSerializer<String> implements ContextualSerializer {
   private PrivacyTypeEnum type;

   private Integer prefixNoMaskLen;

   private Integer suffixNoMaskLen;

   private String maskStr;

   public PrivacySerialize(PrivacyTypeEnum type, Integer prefixNoMaskLen, Integer suffixNoMaskLen, String maskStr) {
      this.type = type;
      this.prefixNoMaskLen = prefixNoMaskLen;
      this.suffixNoMaskLen = suffixNoMaskLen;
      this.maskStr = maskStr;
   }
   public PrivacySerialize() {
   }

   @Override
   public void serialize(String origin, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
      if (ObjectUtil.isNotEmpty(origin) && null != type) {
         switch (type) {
            case CHINESE_NAME:
               jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
               break;
            case ID_CARD:
               jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
               break;
            case FIXED_PHONE:
               jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin));
               break;
            case MOBILE_PHONE:
               jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
               break;
            case ADDRESS:
               jsonGenerator.writeString(DesensitizedUtils.address(origin));
               break;
            case EMAIL:
               jsonGenerator.writeString(DesensitizedUtils.email(origin));
               break;
            case BANK_CARD:
               jsonGenerator.writeString(DesensitizedUtils.bankCard(origin));
               break;
            case PASSWORD:
               jsonGenerator.writeString(DesensitizedUtils.password(origin));
               break;
            case KEY:
               jsonGenerator.writeString(DesensitizedUtils.key(origin));
               break;
            case enDecrypt:
               jsonGenerator.writeString(DesensitizedUtils.enDecrypt(origin));
               break;
            case CUSTOMER:
               jsonGenerator.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, maskStr));
               break;
            default:
               throw new IllegalArgumentException("Unknow sensitive type enum " + type);
         }
      }else {
         jsonGenerator.writeString("");
      }

   }

   @Override
   public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
      if (beanProperty != null) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
               PrivacyEncrypt encrypt = beanProperty.getAnnotation(PrivacyEncrypt.class);
               if (encrypt == null) {
                  encrypt = beanProperty.getContextAnnotation(PrivacyEncrypt.class);
               }
               if (encrypt != null) {
                  return new PrivacySerialize(encrypt.type(), encrypt.prefixNoMaskLen(),
                        encrypt.suffixNoMaskLen(), encrypt.maskStr());
               }
            }
         return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
      }
      return serializerProvider.findNullValueSerializer(null);
   }
}
